﻿jQuery.extend(jQuery.prototype, {
    SearchTree: function (settings) {
        var thisobj = this; 	//当前对象
        var id = thisobj.attr("id");
        var height = thisobj.height(); 	//当前对象的高度
        var paddingLeft = parseInt(thisobj.css("paddingLeft").replace("px", ""));
        var paddingRight = parseInt(thisobj.css("paddingRight").replace("px", ""));
        var width = thisobj.width() + paddingLeft + paddingRight + 2; 	//当前对象的宽度

        var options = jQuery.extend({
            data: [], 	//数据
            TreeWidth: 0, //定义浮层宽度,默认最小宽度为文本框宽度，随内容自动增宽
            factWidth: 500, //定义内容页的实际宽度，为了避免文本过长导致错位
            TextStrlen: 0, //定义截取字体的长度，默认不截字
            TreeMaxHeight: 332, //定义浮层的最大高度，默认332像素
            NodeHeight: 20, //定义节点高度，默认24像素
            TreeBtnId: "TreeBtnDiv",
            BtnWidth: 0, //定义右边按钮的宽度
            defaultText: "请选择...", //定义文本框的初始值，也就是未选中的值
            defaultVal: "", //默认一开始选中其中某条时需要定义这个值
            defaultSelRoot: false, //是否选中根节点，默认不选中
            showNumFloor: 1, //默认一开始展开前面1层,设置时不能小于1,没人会在一开始时只愿意看到一个根节点吧
            onChange: function (val) { }, //onChange事件，由调用者覆盖,默认不做任何处理,第一个参数为更改的值
            imgUrl: {
                "root": AC_ROOT_DIR + "/Content/Libs/searchTree/images/root.png",
                "hide": [AC_ROOT_DIR + "/Content/Libs/searchTree/images/P0.gif", AC_ROOT_DIR + "/Content/Libs/searchTree/images/P1.gif", AC_ROOT_DIR + "/Content/Libs/searchTree/images/P2.gif", AC_ROOT_DIR + "/Content/Libs/searchTree/images/P3.gif"],
                "show": [AC_ROOT_DIR + "/Content/Libs/searchTree/images/M0.gif", AC_ROOT_DIR + "/Content/Libs/searchTree/images/M1.gif", AC_ROOT_DIR + "/Content/Libs/searchTree/images/M2.gif", AC_ROOT_DIR + "/Content/Libs/searchTree/images/M3.gif"],
                "contact": [AC_ROOT_DIR + "/Content/Libs/searchTree/images/L0.gif", AC_ROOT_DIR + "/Content/Libs/searchTree/images/L1.gif", AC_ROOT_DIR + "/Content/Libs/searchTree/images/L2.gif", AC_ROOT_DIR + "/Content/Libs/searchTree/images/L3.gif", AC_ROOT_DIR + "/Content/Libs/searchTree/images/L4.gif", AC_ROOT_DIR + "/Content/Libs/searchTree/images/L5.gif"]
            }
        }, settings);

        //是否截取字符
        var textTruncation = function (text) {
            if (options.TextStrlen != 0) {
                return SetStrLength(text, options.TextStrlen) + '...';
            }
            return text;
        }

        //初始化数据库查询出来的源JSON数据
        var initTreeData = function (data, pobj) {
            for (var i = 0, l = data.length; i < l; ++i) {
                if (data[i].pid == pobj.id) {
                    var bgImg = "";
                    if (data[i].bgImg) bgImg = data[i].bgImg;
                    pobj.children.push({ "id": data[i].id, "val": data[i].val, "text": data[i].text, "bgImg": bgImg, "children": [] });
                    initTreeData(data, pobj.children[pobj.children.length - 1]);
                }
            }
        }
        if (options.data.length > 0) {
            var TreeObj = { "id": 0, "val": options.data[0].val, "text": options.data[0].text, "children": [] };
            initTreeData(options.data, TreeObj);
        }

        //数据初始化结束


        //初始化界面树的包框
        var init = function () {
            $("#" + id).val(options.defaultText);
            $("#" + id).attr("title", options.defaultText);

            if (options.data.length <= 0) return;
            var leftpx = thisobj.get(0).offsetLeft; //当前对象的距离左边距离
            var toppx = thisobj.get(0).offsetTop; 	//当前对象的距离顶部距离

            var TreeWidth = 'min-width:' + (width - 2 + options.BtnWidth) + 'px;';
            var html = '<div class="searchTree-Div" id="searchTree-Div-' + id + '" style="' + TreeWidth + ' max-height:' + options.TreeMaxHeight + 'px;"></div><input type="hidden" id="searchTree-hidden-' + id + '">';
            $("body").append(html);

            var flag = true;
            if (options.defaultVal != "") {
                for (var i = 0, l = options.data.length; i < l; ++i) {
                    if (options.data[i].val == options.defaultVal) {
                        $("#" + id).val(textTruncation(options.data[i].text));
                        $("#searchTree-hidden-" + id).val(options.defaultVal);
                        flag = false;
                        break;
                    }
                }

            }
            if (flag && options.defaultSelRoot) {
                $("#" + id).val(textTruncation(options.data[0].text));
                $("#searchTree-hidden-" + id).val(options.data[0].val);
            }
            if (options.showNumFloor < 1) options.showNumFloor = 1;
        }
        init();



        $("#" + id + ", #" + options.TreeBtnId).click(function () {
            if (options.data && options.data.length <= 0) return;

            $("#" + id).val("");
            $("#" + id).attr("title", "");
            $("#" + id).css("cursor", "text");
            $("#" + id).focus();
            var curVal = $("#searchTree-hidden-" + id).val();

            var leftpx = thisobj.offset().left; //当前对象的距离左边距离
            var toppx = thisobj.offset().top; 	//当前对象的距离顶部距离
            $("#searchTree-Div-" + id).css("left", leftpx);
            $("#searchTree-Div-" + id).css("top", toppx + height + 3);

            window.scrollNum = 0;
            window.NodeNum = 0;
            window.tmpFlag = true;
            var tmpClass = "";
            if (curVal != "" && TreeObj.val == curVal) {
                tmpClass = ' class="cur"';
                tmpFlag = false;
            }
            window.TreeHtml = '<div class="node_0"><img src="' + options.imgUrl.root + '"><span' + tmpClass + ' val="' + TreeObj.val + '" title="' + TreeObj.text + '" style="height:' + options.NodeHeight + 'px; line-height:' + options.NodeHeight + 'px;">' + textTruncation(TreeObj.text) + '</span></div>';

            getHtmlByObjChildren(TreeObj.children, 1, curVal, []);
            if (tmpFlag) scrollNum = 0;

            $("#searchTree-Div-" + id).html(TreeHtml);

            if (options.TreeWidth != 0) {
                $("#searchTree-Div-" + id + " div.node_0_div, #searchTree-Div-" + id + " div.node_1_div, #searchTree-Div-" + id + " div.node_2_div, #searchTree-Div-" + id + " div.node_3_div, #searchTree-Div-" + id + " div.node_4_div")
                .width(options.factWidth);
                $("#searchTree-Div-" + id).width(options.TreeWidth);
            }


            if ($("#searchTree-Div-" + id + " span.cur").length > 0) {
                var curJqObj = $("#searchTree-Div-" + id + " span.cur").eq(0);
                var curNodeNum = curJqObj.parent().attr("class").replace("  searchShow", "").split("_")[1];
                curJqObj = curJqObj.parent();
                for (var i = 0; i < curNodeNum - 1; ++i) {
                    curJqObj.parent().css("display", "block");
                    if (curJqObj.parent().prev() && curJqObj.parent().prev().attr("class") && curJqObj.parent().prev().attr("class") != "node_0") curJqObj.parent().prev().find("img:last").removeClass("hideImgBtn").addClass("showImgBtn").attr("src", options.imgUrl.show[0]);
                    curJqObj = curJqObj.parent();
                }
            }

            SpanBindClick();
            ImgBtnClick();

            $("#searchTree-Div-" + id).slideDown();

            if (scrollNum > 0) {
                //$("#testdiv").append("当前距离个数：" + scrollNum + "<br>");
                var DivScrollTop = (scrollNum + 1) * options.NodeHeight - options.TreeMaxHeight;
                $("#searchTree-Div-" + id).get(0).scrollTop = DivScrollTop;
            }
        });

        var ImgBtnClick = function () {
            $("#searchTree-Div-" + id + " .showImgBtn").click(function () {
                if (options.TreeWidth == 0) $("#searchTree-Div-" + id + " div.node_0_div, #searchTree-Div-" + id + " div.node_1_div, #searchTree-Div-" + id + " div.node_2_div, #searchTree-Div-" + id + " div.node_3_div, #searchTree-Div-" + id + " div.node_4_div")
                .width("auto");
                $(this).parent().next().slideUp();

                $(this).attr("src", options.imgUrl.hide[3]);
                $(this).removeClass("showImgBtn").addClass("hideImgBtn");
                $("#searchTree-Div-" + id + " .showImgBtn, #searchTree-Div-" + id + " .hideImgBtn").unbind("click");
                ImgBtnClick();
            });

            $("#searchTree-Div-" + id + " .hideImgBtn").click(function () {
                $(this).parent().next().slideDown();

                if (options.TreeWidth == 0) $("#searchTree-Div-" + id + " div.node_0_div, #searchTree-Div-" + id + " div.node_1_div, #searchTree-Div-" + id + " div.node_2_div, #searchTree-Div-" + id + " div.node_3_div, #searchTree-Div-" + id + " div.node_4_div")
                .width($("#searchTree-Div-" + id).width() + 10);

                $(this).attr("src", options.imgUrl.show[0]);
                $(this).removeClass("hideImgBtn").addClass("showImgBtn");
                $("#searchTree-Div-" + id + " .showImgBtn, #searchTree-Div-" + id + " .hideImgBtn").unbind("click");
                ImgBtnClick();
            });
        }

        var SpanBindClick = function () {
            $("#searchTree-Div-" + id + " span").click(function () {
                var spanVal = $(this).attr("val");
                var spanText = $(this).attr("title");
                $("#" + id).val(textTruncation(spanText));
                $("#" + id).attr("title", spanText);
                $("#searchTree-Div-" + id).slideUp();
                if ($("#searchTree-hidden-" + id).val() != spanVal) {
                    $("#searchTree-hidden-" + id).val(spanVal);
                    //$("#searchTree-Div-" + id).slideUp();
                    options.onChange(spanVal);
                }
            });
        }


        thisobj.keyup(function (e) {
            if (e.keyCode == 116) return;
            if (options.data && options.data.length <= 0) return;

            $("#searchTree-Div-" + id).width("auto");
            var searchTxt = thisobj.val();
            if (searchTxt == "") {
                thisobj.click();
                return;
            }
            var curVal = $("#searchTree-hidden-" + id).val();

            var tmpClass = "";
            if (curVal != 0 && TreeObj.val == curVal) {
                tmpClass = ' class="cur"';
            }
            window.TreeHtml = '<div class="node_0"><img src="' + options.imgUrl.root + '"><span' + tmpClass + ' val="' + TreeObj.val + '" title="' + TreeObj.text + '" style="height:' + options.NodeHeight + 'px; line-height:' + options.NodeHeight + 'px;">' + textTruncation(TreeObj.text) + '</span></div>';

            getHtmlByObjChildrenAndSearchTxt(TreeObj.children, 1, curVal, searchTxt);
            $("#searchTree-Div-" + id).html(TreeHtml);


            var tmpMaxW = $("#searchTree-Div-" + id).width();
            $("#searchTree-Div-" + id + " div.node_0_div, #searchTree-Div-" + id + " div.node_1_div, #searchTree-Div-" + id + " div.node_2_div, #searchTree-Div-" + id + " div.node_3_div")
                .width(tmpMaxW + 60);
            if (options.TreeWidth == 0) {
                $("#searchTree-Div-" + id).width(tmpMaxW);
            } else {
                $("#searchTree-Div-" + id).width(options.TreeWidth);
            }
            $("#searchTree-Div-" + id + " div.searchShow").each(function () {
                var tmpNodeNum = $(this).attr("class").replace("  searchShow", "").split("_")[1];
                //var NodeNum = tmpNodeArr[1]
                var obj = $(this);
                for (var i = 0; i < tmpNodeNum; ++i) {
                    if (obj.parent().prev().css("display") == "none") {
                        obj.parent().prev().css("display", "block");
                        obj.parent().prev().addClass("searchShow");
                    }
                    obj = obj.parent();
                }

                if ($(this).next() && $(this).next().attr("class") && $(this).next().attr("class") == $(this).attr("class").replace("  searchShow", "") + "_div") {
                    var tFlagBool = true;
                    $(this).next().find("div").each(function () {
                        if ($(this).css("display") != "none") tFlagBool = false;
                    });
                    if (tFlagBool) $(this).find("img:last").attr("src", options.imgUrl.show[3]).removeClass();
                }
                $(this).parent().find("div.searchShow:last").find("img:last").attr("src", options.imgUrl.contact[2]);
            });
            var pObj_One = $("#searchTree-Div-" + id + " div.searchShow:last").parent().prev();
            if (pObj_One.attr("class") && pObj_One.attr("class") != "node_0" && pObj_One.find("img:first").attr("src") != options.imgUrl.contact[5]) pObj_One.find("img:first").attr("src", options.imgUrl.contact[2]);
            $("#searchTree-Div-" + id + " div.searchShow:last").find("img:first").attr("src", options.imgUrl.contact[5]);
            if ($("#searchTree-Div-" + id + " div.searchShow:last").find("img:last").attr("src") != options.imgUrl.show[3]) $("#searchTree-Div-" + id + " div.searchShow:last").find("img:last").attr("src", options.imgUrl.contact[2]);


            SpanBindClick();
            ImgBtnClick();

            $("#searchTree-Div-" + id).slideDown();
        });


        var eventfunc = doAdd();
        eventfunc(document, 'mousedown', function (event) {
            if (!event) {
                event = window.event;
            }
            var tmpId = "searchTree-Div-" + id;
            var el = $(event.srcElement || event.target);
            if (el[0].id != tmpId && el.parents('#' + tmpId).length == 0 && el[0] != $("#" + id).get(0) && el[0] != $("#" + options.TreeBtnId).get(0)) {
                var curVal = $("#searchTree-hidden-" + id).val();
                var flag = true;
                for (var i = 0, l = options.data.length; i < l; ++i) {
                    if (curVal != "" && curVal == options.data[i].val) {
                        $("#" + id).val(textTruncation(options.data[i].text));
                        $("#" + id).attr("title", options.data[i].text);
                        flag = false;
                        break;
                    }
                }
                if (flag) $("#" + id).val(options.defaultText);
                $("#searchTree-Div-" + id).slideUp();
                $("#" + id).css("cursor", "default");
            }
        }, false);


        //递归获取HTML
        var getHtmlByObjChildren = function (data, num, curVal, parentIsLastArr) {
            var styleShowOrHide = "";
            if (options.showNumFloor < num) styleShowOrHide = ' style="display:none"';
            TreeHtml += '<div class="node_' + (num - 1) + '_div"' + styleShowOrHide + '>';
            for (var i = 0, l = data.length; i < l; ++i) {
                if (tmpFlag && options.showNumFloor >= num) scrollNum++;
                var tmpClass = "";
                if (curVal != "" && data[i].val == curVal) {
                    tmpClass = ' class="cur"';
                    if (tmpFlag && options.showNumFloor < num) scrollNum += i + 1;
                    tmpFlag = false;
                }

                var tmpIsLastArr = new Array();
                var conImg = new Array();
                if (parentIsLastArr && parentIsLastArr.length > 0) {
                    tmpIsLastArr = parentIsLastArr;
                    if (data[i - 1] && data[i - 1].children && data[i - 1].children.length > 0) {
                        tmpIsLastArr.pop();
                    }
                    for (var k = 0; k < tmpIsLastArr.length; ++k) {
                        if (tmpIsLastArr[k]) {
                            conImg.push('<img src="' + options.imgUrl.contact[5] + '">');
                        } else {
                            conImg.push('<img src="' + options.imgUrl.contact[4] + '">');
                        }
                    }
                }

                if (data[i].children.length == 0 && i < (l - 1)) {
                    conImg.push('<img src="' + options.imgUrl.contact[1] + '">');
                } else if (data[i].children.length == 0 && i == (l - 1)) {
                    conImg.push('<img src="' + options.imgUrl.contact[2] + '">');
                } else if (data[i].children.length > 0 && options.showNumFloor > num && i < (l - 1)) {
                    tmpIsLastArr.push(false);
                    conImg.push('<img src="' + options.imgUrl.contact[1] + '">');
                    conImg.push('<img class="showImgBtn" src="' + options.imgUrl.show[0] + '">');
                } else if (data[i].children.length > 0 && options.showNumFloor > num && i == (l - 1)) {
                    tmpIsLastArr.push(true);
                    conImg.push('<img src="' + options.imgUrl.contact[2] + '">');
                    conImg.push('<img class="showImgBtn" src="' + options.imgUrl.show[3] + '">');
                } else if (data[i].children.length > 0 && options.showNumFloor <= num && i < (l - 1)) {
                    tmpIsLastArr.push(false);
                    conImg.push('<img src="' + options.imgUrl.contact[1] + '">');
                    conImg.push('<img class="hideImgBtn" src="' + options.imgUrl.hide[3] + '">');
                } else if (data[i].children.length > 0 && options.showNumFloor <= num && i == (l - 1)) {
                    tmpIsLastArr.push(true);
                    conImg.push('<img src="' + options.imgUrl.contact[2] + '">');
                    conImg.push('<img class="hideImgBtn" src="' + options.imgUrl.hide[3] + '">');
                }

                var bgImg = '';
                if (data[i].bgImg && data[i].bgImg != "") bgImg = ' background-image:url(' + data[i].bgImg + '); background-repeat:no-repeat; padding-left:20px;';
                TreeHtml += '<div class="node_' + num + '">' + conImg.join("") + '<span' + tmpClass + ' val="' + data[i].val + '" title="' + data[i].text + '" style="height:' + options.NodeHeight + 'px; line-height:' + options.NodeHeight + 'px;' + bgImg + '">' + textTruncation(data[i].text) + '</span></div>';

                if (data[i].children.length > 0) {
                    getHtmlByObjChildren(data[i].children, num + 1, curVal, tmpIsLastArr);
                }
            }
            TreeHtml += '</div>';

            if (num > NodeNum) NodeNum = num;
        }


        //递归获取HTML
        var getHtmlByObjChildrenAndSearchTxt = function (data, num, curVal, searchTxt, parentIsLastArr) {
            TreeHtml += '<div class="node_' + (num - 1) + '_div">';
            for (var i = 0, l = data.length; i < l; ++i) {
                var tmpClass = "";
                if (curVal != "" && data[i].val == curVal) {
                    tmpClass = ' class="cur"';
                }

                var tmpIsLastArr = new Array();
                var conImg = new Array();
                if (parentIsLastArr) {
                    tmpIsLastArr = parentIsLastArr;
                    if (data[i - 1] && data[i - 1].children && data[i - 1].children.length > 0) {
                        tmpIsLastArr.pop();
                    }
                    for (var k = 0; k < tmpIsLastArr.length; ++k) {
                        if (tmpIsLastArr[k]) {
                            conImg.push('<img src="' + options.imgUrl.contact[5] + '">');
                        } else {
                            conImg.push('<img src="' + options.imgUrl.contact[4] + '">');
                        }
                    }
                }

                if (data[i].children.length == 0 && i < (l - 1)) {
                    conImg.push('<img src="' + options.imgUrl.contact[1] + '">');
                } else if (data[i].children.length == 0 && i == (l - 1)) {
                    conImg.push('<img src="' + options.imgUrl.contact[2] + '">');
                } else if (data[i].children.length > 0 && i < (l - 1)) {
                    tmpIsLastArr.push(false);
                    conImg.push('<img src="' + options.imgUrl.contact[1] + '">');
                    conImg.push('<img class="showImgBtn" src="' + options.imgUrl.show[0] + '">');
                } else if (data[i].children.length > 0 && i == (l - 1)) {
                    tmpIsLastArr.push(true);
                    conImg.push('<img src="' + options.imgUrl.contact[2] + '">');
                    conImg.push('<img class="showImgBtn" src="' + options.imgUrl.show[3] + '">');
                }
                var bgImg = '';
                if (data[i].bgImg && data[i].bgImg != "") bgImg = ' background-image:url(' + data[i].bgImg + '); background-repeat:no-repeat; padding-left:20px;';
                var tmpStyle = ' style="display:none"';
                var tmpShowClass = "";
                if (data[i].text.toUpperCase().indexOf(searchTxt.toUpperCase()) >= 0) {
                    tmpStyle = "";
                    tmpShowClass = " searchShow";
                }
                TreeHtml += '<div class="node_' + num + ' ' + tmpShowClass + '"' + tmpStyle + '>' + conImg.join("") + '<span' + tmpClass + ' val="' + data[i].val + '" title="' + data[i].text + '" style="height:' + options.NodeHeight + 'px; line-height:' + options.NodeHeight + 'px;' + bgImg + '">' + textTruncation(data[i].text) + '</span></div>';

                if (data[i].children.length > 0) {
                    getHtmlByObjChildrenAndSearchTxt(data[i].children, num + 1, curVal, searchTxt, tmpIsLastArr);
                }
            }
            TreeHtml += '</div>';
        }

    }
});
function doAdd() {
    if (window.addEventListener) {
        return function (el, eventName, fn, capture) {
            el.addEventListener(eventName, fn, (capture));
        };
    } else if (window.attachEvent) {
        return function (el, eventName, fn, capture) {
            el.attachEvent("on" + eventName, fn);
        };
    } else {
        return function () {
        };
    }
}

function GetStrLength(str) {
    ///<summary>获得字符串实际长度，中文2，英文1</summary>
    ///<param name="str">要获得长度的字符串</param>
    var realLength = 0, len = str.length, charCode = -1;
    for (var i = 0; i < len; i++) {
        charCode = str.charCodeAt(i);
        if (charCode >= 0 && charCode <= 128) realLength += 1;
        else realLength += 2;
    }
    return realLength;
};

function SetStrLength(str, len) {
    var strlen = 0;
    var s = "";
    for (var i = 0; i < str.length; i++) {
        if (str.charCodeAt(i) > 128) {
            strlen += 2;
        } else {
            strlen++;
        }
        s += str.charAt(i);
        if (strlen >= len) {
            return s;
        }
    }
    return s;
}